package com.dhcc.sdc.busi.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.plugins.Page;
import com.dhcc.core.framework.base.service.impl.BaseServiceImpl;
import com.dhcc.sdc.busi.dao.SdcBusiQcTriggeredMapper;
import com.dhcc.sdc.busi.entity.SdcBusiQcTriggeredEntity;
import com.dhcc.sdc.busi.service.ISdcBusiQcTriggeredService;
import com.dhcc.sds.busi.dto.AnalysisCaseDto;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;


/**
 * 质控条目触发记录表数据服务层接口
 *
 * @author zhangdc
 * @ClassName: SdcBusiQcTriggeredServiceImpl
 * @Description: TODO
 * @date 2022-07-26 14:24:20
 */
@Service("sdcBusiQcTriggeredService")
public class SdcBusiQcTriggeredServiceImpl extends BaseServiceImpl<SdcBusiQcTriggeredMapper, SdcBusiQcTriggeredEntity> implements ISdcBusiQcTriggeredService {

    @Override
    public List<SdcBusiQcTriggeredEntity> page(Page<SdcBusiQcTriggeredEntity> page, Map<String, Object> map) {
        return this.baseMapper.page(page, map);
    }

    @Override
    public List<SdcBusiQcTriggeredEntity> list(Map<String, Object> map) {
        return this.baseMapper.list(map);
    }

    /**
     * @param params
     * @return
     * @Description：查询质控统计数据
     * @Title: selectCaseData
     * @see com.dhcc.sdc.busi.service.ISdcBusiQcTriggeredService#selectQcTrendData(Map)
     */
    @Override
    public JSONObject selectQcTrendData(Map<String, Object> params) {

        JSONObject caseDataObj = new JSONObject();
//        manageIndexService.CommonStatic(params);
        List<Map<String, Object>> caseDataMap = this.baseMapper.selectQcTrendData(params);

        JSONArray chartDatas = new JSONArray();

        JSONArray caseNum = new JSONArray();//患者总数
        JSONArray qcCase = new JSONArray();//触发质控项患者例数
        JSONArray entityNum = new JSONArray();//入组病种数
        JSONArray entityNumTri = new JSONArray();//触发质控病种数
//        JSONArray totalQcNum = new JSONArray();//病种质控项总数
        JSONArray qcTri = new JSONArray();//质控项触发人次数
        JSONArray deptNum = new JSONArray();//涉及科室数
        JSONArray deptNumTri = new JSONArray();//质控触发科室数

        for (Map<String, Object> caseMap : caseDataMap) {
            String ddesc = caseMap.get("firstDate").toString();
            caseNum.add(splitJSONObj(ddesc, caseMap.get("caseNum"), "caseNum"));
            qcCase.add(splitJSONObj(ddesc, caseMap.get("qcCase"), "qcCase"));
            entityNum.add(splitJSONObj(ddesc, caseMap.get("entityNum"), "entityNum"));
            entityNumTri.add(splitJSONObj(ddesc, caseMap.get("entityNumTri"), "entityNumTri"));
//            totalQcNum.add(splitJSONObj(ddesc, caseMap.get("totalQcNum"), "totalQcNum"));
            qcTri.add(splitJSONObj(ddesc, caseMap.get("qcTri"), "qcTri"));
            deptNum.add(splitJSONObj(ddesc, caseMap.get("deptNum"), "deptNum"));
            deptNumTri.add(splitJSONObj(ddesc, caseMap.get("deptNumTri"), "deptNumTri"));
        }
        chartDatas.add(caseNum);
        chartDatas.add(entityNum);
//        chartDatas.add(totalQcNum);
        chartDatas.add(qcTri);
        chartDatas.add(deptNum);
        chartDatas.add(qcCase);
        chartDatas.add(entityNumTri);
        chartDatas.add(deptNumTri);

        caseDataObj.put("chartDatas", chartDatas);
        caseDataObj.put("tableDates", caseDataMap);
        return caseDataObj;
    }

    public JSONObject splitJSONObj(String ddesc, Object rate, String code) {
        JSONObject obj = new JSONObject(new LinkedHashMap<>());
        obj.put(code, rate);
        obj.put("ddesc", ddesc);
        return obj;
    }

    @Override
    public List<Map<String, Object>> getQcCaseList(Map<String, Object> params) {
        List<Map<String, Object>> res = this.baseMapper.getQcCaseList(params);
        return res;
    }

    @Override
    public List<Map<String, Object>> selectQcDetailList(Map<String, Object> params) {
        List<Map<String, Object>> res = this.baseMapper.selectQcDetailList(params);
        return res;
    }

    /**
     * @param params
     * @return
     * @Description：查询上报趋势数据
     * @Title: selectReportTrendData
     * @see com.dhcc.sdc.busi.service.ISdcBusiQcTriggeredService#selectReportTrendData(java.util.Map)
     */
    @Override
    public JSONObject selectReportTrendData(Map<String, Object> params) {

        JSONObject caseDataObj = new JSONObject();
//        manageIndexService.CommonStatic(params);
        List<Map<String, Object>> caseDataMap = this.baseMapper.selectReportTrendData(params);

        int analysisGrain = Integer.parseInt(params.get("analysisGrain").toString());
        if (analysisGrain == 3) {
            Map<String, List<Map<String, Object>>> caseDataGroupMap = new HashMap<>();
            for (Map<String, Object> caseMap : caseDataMap) {
                // 计算季度
                String dishDate = caseMap.get("dishDate").toString();
                String[] split = dishDate.split("-");
                int month = Integer.parseInt(split[1]);
                int quarter = ((month - 1) / 3) + 1;
                String quarterStr = split[0] + "年第" + quarter + "季度";

                List<Map<String, Object>> quarterList = caseDataGroupMap.get(quarterStr);
                if (quarterList == null) {
                    quarterList = new ArrayList<>();
                    caseDataGroupMap.put(quarterStr, quarterList);
                }
                caseMap.put("dishDate", quarterStr);
                caseMap.put("sortStr", split[0] + "-" + quarter);
                quarterList.add(caseMap);
            }

            caseDataMap = new ArrayList<>();
            Iterator<Map.Entry<String, List<Map<String, Object>>>> caseDataGroupIterator = caseDataGroupMap.entrySet().iterator();
            while (caseDataGroupIterator.hasNext()) {
                Map.Entry<String, List<Map<String, Object>>> caseDataGroupEntry = caseDataGroupIterator.next();
                List<Map<String, Object>> caseDataGroup = caseDataGroupEntry.getValue();
                HashMap<String, Object> caseMap = new HashMap<>();
                caseMap.put("dishDate", caseDataGroup.get(0).get("dishDate"));
                caseMap.put("sortStr", caseDataGroup.get(0).get("sortStr"));
                BigDecimal averageMedeCost = new BigDecimal(0); // 平均药费
                BigDecimal consumCost3 = new BigDecimal(0); // 手术用一次性医用材料费（总）
                BigDecimal consistentNum = new BigDecimal(0); // 患者人数
                BigDecimal averageHosDays = new BigDecimal(0); // 次均住院日
                BigDecimal consumCost2 = new BigDecimal(0); // 治疗用一次性医用材料费（总）
                BigDecimal consumCost4 = new BigDecimal(0); // 手术用一次性医用材料费（总）
                BigDecimal reportedRate = new BigDecimal(0); // 上报率
                BigDecimal consumCost1 = new BigDecimal(0); // 检查用一次性医用材料费（总）
                BigDecimal averageHosCost = new BigDecimal(0); // 次均住院费用
                BigDecimal deathRate = new BigDecimal(0); // 死亡率
                Long surgeryNum = 0L; // 手术并发症例数
                BigDecimal deathNum = new BigDecimal(0); // 死亡数
                BigDecimal reported = new BigDecimal(0); // 上报数
                BigDecimal surgeryRate = new BigDecimal(0); // 手术并发症发生率
                for (Map<String, Object> caseData : caseDataGroup) {
                    consistentNum = consistentNum.add((BigDecimal) caseData.get("consistentNum"));
                    consumCost3 = consumCost3.add((BigDecimal) caseData.get("consumCost3"));
                    consumCost2 = consumCost2.add((BigDecimal) caseData.get("consumCost2"));
                    consumCost4 = consumCost4.add((BigDecimal) caseData.get("consumCost4"));
                    consumCost1 = consumCost1.add((BigDecimal) caseData.get("consumCost1"));
                    surgeryNum += (Long) caseData.get("surgeryNum");
                    deathNum = deathNum.add((BigDecimal) caseData.get("deathNum"));
                    reported = reported.add((BigDecimal) caseData.get("reported"));
                    averageMedeCost = averageMedeCost.add(((BigDecimal) caseData.get("consistentNum")).multiply((BigDecimal) caseData.get("averageMedeCost")));
                    averageHosDays = averageHosDays.add(((BigDecimal) caseData.get("consistentNum")).multiply((BigDecimal) caseData.get("averageHosDays")));
                    averageHosCost = averageHosCost.add(((BigDecimal) caseData.get("consistentNum")).multiply((BigDecimal) caseData.get("averageHosCost")));
                }
                averageMedeCost = averageMedeCost.divide(consistentNum, 2, BigDecimal.ROUND_HALF_UP);
                averageHosDays = averageHosDays.divide(consistentNum, 2, BigDecimal.ROUND_HALF_UP);
                averageHosCost = averageHosCost.divide(consistentNum, 2, BigDecimal.ROUND_HALF_UP);
                reportedRate = reported.multiply(BigDecimal.valueOf(100)).divide(consistentNum, 2, BigDecimal.ROUND_HALF_UP);
                deathRate = deathNum.multiply(BigDecimal.valueOf(100)).divide(consistentNum, 2, BigDecimal.ROUND_HALF_UP);
                surgeryRate = BigDecimal.valueOf(surgeryNum).multiply(BigDecimal.valueOf(100)).divide(consistentNum, 2, BigDecimal.ROUND_HALF_UP);

                caseMap.put("averageMedeCost", averageMedeCost);
                caseMap.put("consumCost3", consumCost3);
                caseMap.put("consistentNum", consistentNum);
                caseMap.put("averageHosDays", averageHosDays);
                caseMap.put("consumCost2", consumCost2);
                caseMap.put("consumCost4", consumCost4);
                caseMap.put("reportedRate", reportedRate);
                caseMap.put("consumCost1", consumCost1);
                caseMap.put("averageHosCost", averageHosCost);
                caseMap.put("deathRate", deathRate);
                caseMap.put("surgeryNum", surgeryNum);
                caseMap.put("deathNum", deathNum);
                caseMap.put("reported", reported);
                caseMap.put("surgeryRate", surgeryRate);
                caseDataMap.add(caseMap);
            }
            Collections.sort(caseDataMap, new Comparator<Map<String, Object>>() {
                @Override
                public int compare(Map o1, Map o2) {
                    String sortStr1 = o1.get("sortStr").toString();
                    String[] split1 = sortStr1.split("-");
                    String sortStr2 = o2.get("sortStr").toString();
                    String[] split2 = sortStr2.split("-");
                    int year = Integer.parseInt(split1[0]) - Integer.parseInt(split2[0]);
                    int month = Integer.parseInt(split1[1]) - Integer.parseInt(split2[1]);
                    if (year != 0) {
                        return year;
                    }
                    return month;
                }
            });
        }

        JSONArray chartDatas = new JSONArray();
        JSONArray chartUPDatas = new JSONArray();
        JSONArray chartDeathAndSurDatas = new JSONArray();
        JSONArray chartAverHosDatas = new JSONArray();


        JSONArray reportedRate = new JSONArray();//上报率
        JSONArray deathRate = new JSONArray();//死亡率
        JSONArray averageHosDays = new JSONArray();//次均住院日
        JSONArray averageHosCost = new JSONArray();//次均住院费用
        JSONArray averageConsumCost = new JSONArray();//平均耗材费
        JSONArray averageMedeCost = new JSONArray();//平均药费
        JSONArray surgeryRate = new JSONArray(); //手术并发症发生率


        for (Map<String, Object> caseMap : caseDataMap) {
            String ddesc = caseMap.get("dishDate").toString();
            reportedRate.add(splitJSONObj(ddesc, caseMap.get("reportedRate"), "reportedRate"));
            deathRate.add(splitJSONObj(ddesc, caseMap.get("deathRate"), "deathRate"));
            surgeryRate.add(splitJSONObj(ddesc,caseMap.get("surgeryRate"),"surgeryRate"));
            averageHosDays.add(splitJSONObj(ddesc, caseMap.get("averageHosDays"), "averageHosDays"));
            averageHosCost.add(splitJSONObj(ddesc, caseMap.get("averageHosCost"), "averageHosCost"));
            BigDecimal consumCost1 = (BigDecimal) caseMap.get("consumCost1");
            BigDecimal consumCost2 = (BigDecimal) caseMap.get("consumCost2");
            BigDecimal consumCost3 = (BigDecimal) caseMap.get("consumCost3");
            BigDecimal consumCost = consumCost1.add(consumCost2).add(consumCost3);
            BigDecimal consistentNum = (BigDecimal) caseMap.get("consistentNum");
            DecimalFormat df = new DecimalFormat("0.00");
            String res = df.format(consumCost.divide(consistentNum, 2, BigDecimal.ROUND_HALF_UP));
            averageConsumCost.add(splitJSONObj(ddesc, res, "averageConsumCost"));
            averageMedeCost.add(splitJSONObj(ddesc, caseMap.get("averageMedeCost"), "averageMedeCost"));
            caseMap.put("averageConsumCost", res);
        }

        chartUPDatas.add(reportedRate);
        chartAverHosDatas.add(averageHosDays);

        chartDatas.add(averageHosCost);
        chartDatas.add(averageConsumCost);
        chartDatas.add(averageMedeCost);
        chartDeathAndSurDatas.add(deathRate);
        chartDeathAndSurDatas.add(surgeryRate);

        caseDataObj.put("chartUPDatas", chartUPDatas);
        caseDataObj.put("chartDeathAndSurDatas", chartDeathAndSurDatas);
        caseDataObj.put("chartAverHosDatas", chartAverHosDatas);
        caseDataObj.put("chartDatas", chartDatas);
        caseDataObj.put("tableDates", caseDataMap);
        return caseDataObj;
    }

    @Override
    public List<AnalysisCaseDto> selectPatTrendCaseList(Map<String, Object> params) {
        String key = (String) params.get("key");

        List<AnalysisCaseDto> patTrendList = new ArrayList<>();
        if (Objects.equals("consistentNum", key)) {
            patTrendList = this.baseMapper.selectPatTrend(params);
        } else if (Objects.equals("reported", key)) {
            patTrendList = this.baseMapper.selectPatTrendRE(params);
        } else if (Objects.equals("deathNum", key)) {
            patTrendList = this.baseMapper.selectPatTrendDeath(params);
        }
        else if (Objects.equals("surgeryNum",key)){
            patTrendList = this.baseMapper.selectPatsurgery(params);
        }
        return patTrendList;
    }
}